

Array.prototype.unique = function () {
    var len = this.length,
        obj = {},
        lin = [];
    for (var i = 0; i < len; i++) {
        if (obj[this[i]] === undefined) {
            obj[this[i]] = 'wocao';
            lin.push(this[i]);
        }

    }
    return lin;
}

function distinct(arr) {
    let obj = {}
    let newArr = []
    for (let i = 0; i < arr.length; i++) {
        if (!obj[arr[i]]) {
            obj[arr[i]] = 1
            newArr.push(arr[i])
        }
    }
    return newArr
}

(function (global) {
    function jQuery(dom) {
        return new jQuery.prototype.init(dom);
    }
    function myIn(str, item) {
        return str.indexOf(item) !== -1 ? true : false;
    }
    jQuery.prototype.init = function (dom) {
        this.length = 0;
        var domObj;
        var domStr;
        var num;

        if (dom == null) { // 传参为空时
            return this;
        }
        if (typeof dom === 'string') {//参数为字符串
            if (myIn(dom, ':')) { // 参数中有修饰
                console.log(dom);
                let condition = dom.split(':')[1];
                domStr = dom.split(':')[0];
                console.log(condition, domStr);
                if (myIn(condition, 'eq')) { //参数修饰为eq
                    let reg = /[0-9]+/g;
                    num = Number(condition.match(reg)[0]);
                }
            } else {
                domStr = dom;
            }
            if (myIn(domStr, '.')) {// 为css选择器时
                domObj = document.getElementsByClassName(domStr.slice(1));
            } else if (myIn(domStr, '#')) {// 为id选择器时
                domObj = document.getElementById(domStr.slice(1));
            } else { // 为标签选择器时
                domObj = document.getElementsByTagName(domStr);
            }
        }

        if (typeof num === 'number') { // eq中有参数并为数字
            this[0] = domObj[num];
            this.length++;
        } else { //没有修饰符时
            if (dom instanceof Element || !domObj.length) {// 参数为dom对象 或 id选择器
                this[0] = domObj || dom;
                this.length++;
            } else {// 处理css选择器 或 标签选择器时
                for (let i = 0; i < domObj.length; i++) {
                    this[i] = domObj[i];
                    this.length++;
                }
            }
        }
    }
    //css方法
    jQuery.prototype.css = function (cssObj) {
        for (let i = 0; i < this.length; i++) {
            for (let attr in cssObj) {
                this[i].style[attr] = cssObj[attr];
            }
        }
        return this;
    }
    //get方法
    jQuery.prototype.get = function (num) {
        return num != null ? (num < 0 ? this[this.length + num] : this[num]) : null;
    }
    //eq方法
    jQuery.prototype.eq = function (num) {
        var temp = num != null ? (num < 0 ? this[this.length + num] : this[num]) : null;
        return jQuery(temp);
    }
    // 队列  queue
    jQuery.prototype.myQueue = function (type, fun) {
        var queueBox = this;
        type = type || 'fx';
        fun = fun || null;
        var len = arguments.length;
        if (len === 1 && typeof type === 'string') {
            return queueBox[0][type];
        }
        queueBox[0][type] === undefined ? queueBox[0][type] = [fun] : queueBox[0][type].push(fun);
        return this
    }
    // 取出队列方法 执行
    jQuery.prototype.myDequeue = function (type) {
        console.log(this)
        type = type || 'fx';
        var _that = this;
        var queueBox = this.myQueue(type);
        console.log(queueBox);
        var fun = queueBox.shift();
        if (fun === undefined) {
            return
        }
        var next = function () {
            _that.myDequeue(type);
            // console.log('ok')
        }
        fun(next);
    }
    // 动画方法
    jQuery.prototype.myAnimate = function () {

    }
    // 去重
    jQuery.unique = function (arr) {
        var newArr = [];
        var tempObj = {};
        for (var i = 0; i < arr.length; i++) {
            if (tempObj[arr[i]] === undefined) {
                tempObj[arr[i]] = 's';
                newArr.push(arr[i])
            }
        }
        return newArr;
    }
    // 回调队列
    jQuery.MyCallbacks = function () {
        var options = arguments[0] ||M '';
        var list = [];
        var fireIndex = 0;
        var isFire = false;
        var args = [];
        var _that = this;
        function fire() {
            for (; fireIndex < list.length; fireIndex++) {
                // if (list[fireIndex] !== 'function') break
                var onFalse = list[fireIndex].apply(window, args);
                if (options.indexOf('stopOnFalse') !== -1) {
                    if (onFalse === false) {
                        break
                    }
                    fireIndex = 0;

                }
            }
            if (options.indexOf('once') !== -1) {
                list = [];
                fireIndex = 0;
            }
        }
        return {
            add: function (fun) {
                // if (options.indexOf('unique') !== -1) {
                //     for (var i = 0; i < list.length; i ++) {
                //         if(list[i] === fun) {
                //             return
                //         }
                //     }
                // }
                list.push(fun);

                if (options.indexOf('unique') !== -1) {
                    list = _that.unique(list);
                }

                if (options.indexOf('memory') !== -1 && isFire) {
                    fire();
                }
                return this;
            },
            fire: function () {
                fireIndex = 0;
                args = arguments;
                isFire = true;
                fire();
            }
        }
    }
    // 异步 带状态的 回调函数
    jQuery.MyDeferred = function () {
        var callBox = [
            [jQuery.MyCallbacks('once memory'), 'done', 'resolve'],
            [jQuery.MyCallbacks('once memory'), 'fail', 'reject'],
            [jQuery.MyCallbacks('memory'), 'progress', 'notify']
        ];
        var flag = true;
        function Deferred() {
            var _that = this;
            for (var i = 0; i < callBox.length; i++) {
                this[callBox[i][1]] = (function (index) {
                    return function (fun) {
                        callBox[index][0].add(fun);
                    }
                })(i);
                this[callBox[i][2]] = (function (index) {
                    return function () {
                        var args = arguments;
                        if (flag) {
                            callBox[index][0].fire.apply(window, args);
                            callBox[index][2] === 'resolve' || callBox[index][2] === 'reject' ? flag = false : '';
                        }
                    }
                })(i);
            }
            this.then = function (onRes, onRej, onNot) {
                var def = jQuery.MyDeferred();
                callBox[0][0].add(function (args) {
                    var res = onRes(args);
                    handle(res, def.resolve, def.reject, def.notify);
                });
                callBox[1][0].add(function (args) {
                    var res = onRej(args);
                    handle(res, def.resolve, def.reject, def.notify);
                });
                callBox[2][0].add(function (args) {
                    var res = onNot(args);
                    handle({ key: 'notify', res }, def.resolve, def.reject, def.notify);
                });
                return def.promise();
            }
            this.promise = function () {
                var obj = jQuery.MyDeferred();
                obj.then = _that.then;
                obj.done = _that.done;
                obj.fail = _that.fail;
                obj.progress = _that.progress;
                return obj;
            }
        }
        function handle(res, resolve, reject, notify) {
            if (typeof res === 'object' && res.constructor.name === Deferred.name) {
                res.then(function (data) {
                    resolve(data);
                }, function (err) {
                    reject(err)
                }, function (data) {
                    notify(data);
                });
            } else if (typeof res === 'object' && res.key === 'notify') {
                notify(res.res);
            } else {
                resolve(res);
            }
        }
        var def = new Deferred();
        return def;


    }
    jQuery.prototype.init.prototype = jQuery.prototype;
    global.jQuery = global.$ = jQuery;
}(window));
